//------------------------------------------------------------------------------------------------- 
// <copyright file="SublayoutParameterHelper.cs" company="Sitecore Shared Source">
// Copyright (c) Sitecore.  All rights reserved.
// </copyright>
// <summary>Defines the SublayoutParameterHelper type.</summary>
// <license>
// http://sdn.sitecore.net/Resources/Shared%20Source/Shared%20Source%20License.aspx
// </license>
// <url>http://trac.sitecore.net/SublayoutParameterHelper/</url>
//-------------------------------------------------------------------------------------------------

using System.Collections.Specialized;
using System.Reflection;
using Sitecore.Diagnostics;

namespace ColorBox4Sitecore.Helpers
{
    /// <summary>
    /// Helper class to parse parameters and data source passed to a sublayout.
    /// </summary>
    public class SublayoutParameterHelper
    {
        #region Private members
        /// <summary>
        /// Sublayout data source item.
        /// </summary>
        private Sitecore.Data.Items.Item _dataSourceItem;

        #endregion

        #region Public constructors
        /// <summary>
        /// Initializes a new instance of the SublayoutParameterHelper class. Parses
        /// parameters and applies properties as directed.
        /// </summary>
        /// <param name="control">Pass "this" from the user control</param>
        /// <param name="applyProperties">Set user control properties corresponding to
        /// parameter names to parameter values.</param>
        public SublayoutParameterHelper(System.Web.UI.UserControl control, bool applyProperties)
            : this(control, applyProperties, true)
        {
        }

        /// <summary>
        /// Initializes a new instance of the SublayoutParameterHelper class. Parses
        /// parameters and applies properties as directed.
        /// </summary>
        /// <param name="control">Pass "this" from the user control</param>
        /// <param name="applyProperties">Set user control properties corresponding to
        /// parameter names to parameter values.</param>
        /// <param name="canOverwrite">Can a property value be overwritten when it already has a value</param>
        public SublayoutParameterHelper(System.Web.UI.UserControl control, bool applyProperties, bool canOverwrite)
        {
            this.BindingControl = control.Parent as Sitecore.Web.UI.WebControls.Sublayout;

            // Parse parameters passed to the sc:sublayout control.
            if (this.BindingControl == null)
            {
                return;
            }

            this.Parameters = Sitecore.Web.WebUtil.ParseUrlParameters(this.BindingControl.Parameters);

            if (applyProperties)
            {
                this.ApplyProperties(control, canOverwrite);
            }
        }

        #endregion

        #region Public properties
        /// <summary>
        /// Sets the path to the Sitecore data source item.
        /// </summary>
        public string DataSource
        {
            set
            {
                this.DataSourceItem = Sitecore.Context.Database.GetItem(value);
            }
        }

        /// <summary>
        /// Gets or sets the data source item.
        /// </summary>
        protected Sitecore.Data.Items.Item DataSourceItem
        {
            get
            {
                // If the data source has not been set 
                // and this code can access properties of the binding control
                if (this._dataSourceItem == null)
                {
                    if (this.BindingControl == null || string.IsNullOrEmpty(this.BindingControl.DataSource))
                    {
                        this._dataSourceItem = Sitecore.Context.Item;
                    }
                    else if (Sitecore.Context.Database != null)
                    {
                        this._dataSourceItem = Sitecore.Context.Database.GetItem(this.BindingControl.DataSource);
                    }
                }

                return this._dataSourceItem;
            }

            set
            {
                this._dataSourceItem = value;
            }
        }

        #endregion

        #region Protected properties
        /// <summary>
        /// Gets or sets the item to publish.
        /// </summary>
        protected Sitecore.Data.Items.Item Item { get; set; }

        /// <summary>
        /// Gets or sets the parameters passed to the sublayout.
        /// </summary>
        protected NameValueCollection Parameters { get; set; }

        /// <summary>
        /// Gets or sets the sublayout control used when user control binds to Sitecore
        /// placeholder,  or using sc:sublayout control. Otherwiwse Null (when user control
        /// is bound using ASP.NET).
        /// </summary>
        protected Sitecore.Web.UI.WebControls.Sublayout BindingControl { get; set; }

        #endregion

        #region Public methods
        /// <summary>
        /// Return the value of a specific parameter.
        /// </summary>
        /// <param name="key">Parameter name.</param>
        /// <returns>Value of specified parameter.</returns>
        public string GetParameter(string key)
        {
            if (this.Parameters == null)
            {
                return string.Empty;
            }

            string result = this.Parameters[key];

            if (string.IsNullOrEmpty(result))
            {
                return string.Empty;
            }

            return result;
        }

        #endregion

        #region Protected methods
        /// <summary>
        /// Apply parameters passed to the sublayout as properties of the user control.
        /// </summary>
        /// <param name="control">The user control.</param>
        protected void ApplyProperties(System.Web.UI.UserControl control)
        {
            ApplyProperties(control, true);
        }

        /// <summary>
        /// Apply parameters passed to the sublayout as properties of the user control.
        /// </summary>
        /// <param name="control">The user control.</param>
        /// <param name="canOverwrite">Can a property value be overwritten when it already has a vaue</param>
        protected void ApplyProperties(System.Web.UI.UserControl control, bool canOverwrite)
        {
            foreach (string key in this.Parameters.Keys)
            {
                /* get CssClass value and meta data */
                PropertyInfo propertyInfo = Sitecore.Reflection.ReflectionUtil.GetPropertyInfo(control, key);
                if (propertyInfo != null)
                {
                    object propertyValue = propertyInfo.GetValue(control, null);

                    /* only assign a value when the property has no value yet */
                    if (propertyValue == null || string.IsNullOrEmpty(propertyValue.ToString()))
                    {
                        Sitecore.Reflection.ReflectionUtil.SetProperty(control, key, this.Parameters[key]);
                    }
                }
            }

            if (string.IsNullOrEmpty(this.BindingControl.DataSource))
            {
                return;
            }

            Assert.IsNotNull(this.DataSourceItem, string.Format("Datasource item is null for the sublayout: '{0}' into the placeholder: '{1}' check is this item is published", this.BindingControl.Path, control.ID));

            Sitecore.Reflection.ReflectionUtil.SetProperty(control, "datasource", this.DataSourceItem.Paths.FullPath);
            Sitecore.Reflection.ReflectionUtil.SetProperty(control, "datasourceitem", this.DataSourceItem);
        }

        #endregion
    }
}